package com.en.sharing.serviceprovider.bpm;

import com.en.sharing.serviceprovider.bpm.approval.ApprovalService;
import com.alibaba.fastjson.JSON;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;

/**
 * 审批处理处理(依赖底层统一的审批提交)
 *
 * @author 付晓飞
 * @date 2024/3/11 7:14 下午
 */
public final class OperationApprovalProcess<T, R> {

    /**
     * 存放注册进来的审批结果处理方法
     */
    private Map<String, Map<OperateTypeEnum, IOperationApprovalResultProcess<T, R>>> processMap = new HashMap<>();

    private ApprovalService approvalService;

    public OperationApprovalProcess(ApprovalService approvalService) {
        this.approvalService = approvalService;
    }

    /**
     * 服务注册
     *
     * @param taskTypeEnum
     * @param operationTypeEnum
     * @param process
     * @param <T>
     * @param <R>
     */
    public void register(IOperationEntryCode taskTypeEnum,
                                OperateTypeEnum operationTypeEnum,
                                BiFunction<T, T, R> process) {
        final IOperationApprovalResultProcess<T, R> engineProcess = (task, approvalPass) -> {
            if (approvalPass) {
                return process.apply(task.getOldData(), task.getNewData());
            }
            return null;
        };

        if (processMap.containsKey(taskTypeEnum.getCode())) {
            processMap.get(taskTypeEnum.getCode()).put(operationTypeEnum, engineProcess);
        } else {
            Map<OperateTypeEnum, IOperationApprovalResultProcess<T, R>> map = new HashMap<>(4);
            map.put(operationTypeEnum, engineProcess);
            processMap.put(taskTypeEnum.getCode(), map);
        }
    }

    /**
     * 模拟数据库，存放审批任务
     */
    private final Map<String, OperateApprovalTaskBo<T>> taskMap = new ConcurrentHashMap<>();

    public R submit(OperateApprovalTaskBo<T> task) {
        final T oldData = task.getOldData();
        final T newData = task.getNewData();
        if (task.getOperationEntryCode().openApproval()) {
            final String taskId = UUID.randomUUID().toString();
            taskMap.put(taskId, task);
            approvalService.submitApproval(taskId, JSON.parseObject(JSON.toJSONString(oldData), Map.class), JSON.parseObject(JSON.toJSONString(newData), Map.class));
            return null;
        }
        return processMap.get(task.getOperationEntryCode().getCode()).get(task.getOperateType()).processResult(task, true);
    }

    /**
     * 审批结果通知处理
     *
     * @param taskId            任务id
     * @param approvalStatus    审批状态：true 通过 false 不通过
     */
    public void noticeApprovalResultProcess(String taskId, boolean approvalStatus) {
        if (approvalStatus) {
            final OperateApprovalTaskBo<T> task = taskMap.get(taskId);
            processMap.get(task.getOperationEntryCode().getCode()).get(task.getOperateType()).processResult(task, true);
        }
    }

}
